package com.lxg.config;

import com.lxg.security.filter.KaptchaFilter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @author 陆小根
 * date: 2022/04/25
 * Description:
 */
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {


  // 这里没有使用数据库查询
  // 而是根据内存中用户
  @Bean
  public UserDetailsService userDetailsService() {
    InMemoryUserDetailsManager inMemoryUserDetailsManager = new InMemoryUserDetailsManager();
    inMemoryUserDetailsManager.createUser(User.withUsername("root").password("{noop}123").roles("admin").build());
    return inMemoryUserDetailsManager;
  }

  @Override
  protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth.userDetailsService(userDetailsService());
  }

  @Override
  @Bean
  public AuthenticationManager authenticationManagerBean() throws Exception {
    return super.authenticationManagerBean();
  }

  @Bean
  public KaptchaFilter kaptchaFilter() throws Exception {
    KaptchaFilter kaptchaFilter = new KaptchaFilter();
    kaptchaFilter.setFilterProcessesUrl("/doLogin");
    kaptchaFilter.setUsernameParameter("uname");
    kaptchaFilter.setPasswordParameter("passwd");
    kaptchaFilter.setKaptchaParameter("kaptcha");
    // 指定认证管理器
    kaptchaFilter.setAuthenticationManager(authenticationManagerBean());
    // 指定认证成功后处理
    kaptchaFilter.setAuthenticationSuccessHandler(new AuthenticationSuccessHandler() {
      @Override
      public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
        response.sendRedirect("/index.html");
      }
    });
    // 指定认证失败后处理
    kaptchaFilter.setAuthenticationFailureHandler(new AuthenticationFailureHandler() {
      @Override
      public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {
        response.sendRedirect("/login.html");
      }
    });
    return kaptchaFilter;
  }

  @Override
  protected void configure(HttpSecurity http) throws Exception {
    http.authorizeRequests()
            .mvcMatchers("/login.html").permitAll()
            .mvcMatchers("/vc.jpg").permitAll()
            .anyRequest().authenticated() // // 任何请求都必须认证
            .and()
            .formLogin()
            .loginPage("/login.html")
//            .loginProcessingUrl("/doLogin")
//            .usernameParameter("uname")
//            .passwordParameter("passwd")
//            .defaultSuccessUrl("/index.html", true)
//            .failureUrl("/login.html")
            .and()
            .logout()
            .logoutUrl("/logout")
            .and()
            .csrf().disable()
    ;

    http.addFilterAt(kaptchaFilter(), UsernamePasswordAuthenticationFilter.class);
  }
}
